package com.xjoyt.pay.share.services;

import java.util.Date;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import com.xjoyt.pay.abstracts.AbstractService;
import com.xjoyt.pay.dto.ExecuteResult;
import com.xjoyt.pay.dto.PageParam;
import com.xjoyt.pay.dto.PageResult;
import com.xjoyt.pay.share.api.email.EmailClient;
import com.xjoyt.pay.share.dto.EmailSendResult;
import com.xjoyt.pay.share.params.EmailPageParam;
import com.xjoyt.pay.share.params.EmailParam;
import com.xjoyt.pay.share.po.Email;
import com.xjoyt.pay.share.repository.EmailRepository;

@Service
public class EmailService extends AbstractService {

	private static final String EMAIL_CODE_KEY = "key:value.email.code.%s.%s.%s";

	private static final int CODE_LENGTH = 6;

	private static final int CODE_TIMEOUT = 30;

	private static final int COOLDOWN_TIME = 1;

	@Autowired
	private EmailClient emailClient;

	@Autowired
	private EmailRepository repository;

	@Autowired
	private StringRedisTemplate redisTemplate;

	public ExecuteResult<String> send(EmailParam param) {
		Email entity = new Email();
		entity.companyId = param.companyId;
		entity.companyName = param.companyName;
		entity.email = param.to;
		entity.addedDate = new Date();
		ExecuteResult<String> executeResult = null;

		String key = String.format(EMAIL_CODE_KEY, param.action, param.companyId, param.to);
		if (StringUtils.isNotBlank(redisTemplate.opsForValue().get(key + ".time"))) {
			return ExecuteResult.ok("验证码已经发送");
		}
		String code = redisTemplate.opsForValue().get(key);
		if (StringUtils.isBlank(code)) {
			code = getCode();
		}
		try {
			ExecuteResult<EmailSendResult> result = emailClient.send(param, code);
			if (result.isSuccess()) {
				executeResult = ExecuteResult.ok(result.getValue().value);
				entity.success = true;
				entity.content = result.getValue().content;
				redisTemplate.opsForValue().set(key, code, CODE_TIMEOUT, TimeUnit.MINUTES);
				redisTemplate.opsForValue().set(key + ".time", code, COOLDOWN_TIME, TimeUnit.MINUTES);
			} else {
				executeResult = ExecuteResult.fail(result.getMessage());
				entity.success = false;
			}
		} catch (Exception e) {
			e.printStackTrace();
			entity.success = false;
			return ExecuteResult.fail("发送异常");
		}

		repository.save(entity);
		return executeResult;

	}

	public ExecuteResult<String> validate(EmailParam param) {
		String key = String.format(EMAIL_CODE_KEY, param.action, param.companyId, param.to);
		String value = redisTemplate.opsForValue().get(key);
		if (!param.code.equals(value)) {
			return ExecuteResult.fail("验证码有误");
		}
		// redisTemplate.delete(key);
		return ExecuteResult.ok();
	}

	public ExecuteResult<?> remove(EmailParam param) {
		String key = String.format(EMAIL_CODE_KEY, param.action, param.companyId, param.to);
		String value = redisTemplate.opsForValue().get(key);
		if (StringUtils.isNotBlank(value)) {
			redisTemplate.delete(key);
		}
		return ExecuteResult.ok();
	}

	public PageResult<Email> loadPage(PageParam<EmailPageParam> param) {
		return repository.loadPage(param);
	}

	public String getCode() {
		StringBuilder builder = new StringBuilder();
		int codeLength = CODE_LENGTH;
		for (int i = 0; i < codeLength; i++) {
			java.util.Random random = new java.util.Random();
			int r = random.nextInt(10);
			builder.append(String.valueOf(r));
		}
		return builder.toString();
	}

}
